const MessageTypes = {
  Invocation: 1,
  StreamItem: 2,
  Completion: 3,
  StreamInvocation: 4,
  CancelInvocation: 5,
  Ping: 6,
  Close: 7
};

class SignalRClient {
  constructor(baseUrl, hubName) {
    this.baseUrl = baseUrl.replace(/\/$/, '');
    this.hubName = hubName;
    this.socket = null;
    this.connectionId = null;
    this.callbacks = new Map();
    this.handlers = new Map();
    this.messageId = 1;
    this.retryCount = 0;
    this.maxRetries = 5;
    this.retryDelay = 5000;
    this.keepAliveTimer = null;
    this.reconnectEnabled = true;
  }

  // 完整修复后的 connect 方法
  async connect() {
    try {
      const negotiateUrl = `${this.baseUrl}/${this.hubName}/negotiate?negotiateVersion=1`;
      
      // 修改点：直接获取响应对象
      const response = await uni.request({
        url: negotiateUrl,
        method: 'POST',
        header: { 'Content-Type': 'application/json' }
      });
  
      // 错误处理（兼容微信小程序状态码）
      if (response.statusCode !== 200) {
        throw new Error(`Negotiation failed: ${response.data}`);
      }
  
      // 获取连接数据
      const data = response.data;
      if (!data.connectionToken) {
        throw new Error('Invalid negotiation response');
      }
      
      this.connectionId = data.connectionToken;
      
      // 后续连接逻辑保持不变...
    } catch (err) {
      // 统一错误处理
      console.error('Connection error:', err);
      if (this.retryCount < this.maxRetries) {
        this.retryCount++;
        setTimeout(() => this.connect(), this.retryDelay);
        return false;
      }
      throw err;
    }
  }
  async _createWebSocket() {
    return new Promise((resolve, reject) => {
      const wsUrl = `${this.baseUrl}/${this.hubName}?id=${this.connectionId}&negotiateVersion=1`;
      
      this.socket = uni.connectSocket({
        url: wsUrl,
        complete: () => {}
      });

      this.socket.onOpen(() => {
        // 发送握手协议
        const handshake = JSON.stringify({ protocol: 'json', version: 1 });
        this._sendRaw(handshake);
        
        // 监听握手响应
        const handshakeListener = (res) => {
          if (res.data === '{}\u001e') {
            this.socket.offMessage(handshakeListener);
            resolve();
          }
        };
        
        this.socket.onMessage(handshakeListener);
      });

      this.socket.onMessage((res) => this._handleMessage(res.data));
      
      this.socket.onError((err) => {
        console.error('WebSocket error:', err);
        reject(err);
      });

      this.socket.onClose(() => {
        console.log('WebSocket closed');
        this._stopKeepAlive();
        if (this.reconnectEnabled) {
          this.connect();
        }
      });
    });
  }

  // 注册客户端方法
  on(methodName, callback) {
    this.handlers.set(methodName, callback);
  }

  // 调用服务端方法
  async invoke(methodName, ...args) {
    return new Promise((resolve, reject) => {
      const invocationId = this.messageId.toString();
      const message = {
        type: MessageTypes.Invocation,
        target: methodName,
        arguments: args,
        invocationId
      };

      this.callbacks.set(invocationId, { resolve, reject });
      this.messageId++;

      this._sendMessage(message);
    });
  }

  // 关闭连接
  close() {
    this.reconnectEnabled = false;
    this._sendMessage({ type: MessageTypes.Close });
    this.socket.close();
  }

  // 内部消息处理
  _handleMessage(rawData) {
    try {
      const messages = rawData.split('\u001e').filter(s => s);
      messages.forEach(msg => this._processSingleMessage(msg));
    } catch (error) {
      console.error('Message processing error:', error);
    }
  }

  _processSingleMessage(message) {
    try {
      const data = JSON.parse(message);
      
      switch (data.type) {
        case MessageTypes.Invocation:
          this._handleServerInvocation(data);
          break;
          
        case MessageTypes.Completion:
          this._handleCompletion(data);
          break;
          
        case MessageTypes.Ping:
          this._handlePing();
          break;
          
        case MessageTypes.Close:
          console.log('Server requested close:', data.error);
          this.close();
          break;
          
        default:
          console.warn('Unhandled message type:', data.type);
      }
    } catch (error) {
      console.error('Message parse error:', error);
    }
  }

  _handleServerInvocation(data) {
    const handler = this.handlers.get(data.target);
    if (handler) {
      try {
        const result = handler(...data.arguments);
        if (data.invocationId) {
          this._sendCompletion(data.invocationId, null, result);
        }
      } catch (error) {
        this._sendCompletion(data.invocationId, error.toString());
      }
    }
  }

  _handleCompletion(data) {
    const callback = this.callbacks.get(data.invocationId);
    if (callback) {
      if (data.error) {
        callback.reject(new Error(data.error));
      } else {
        callback.resolve(data.result);
      }
      this.callbacks.delete(data.invocationId);
    }
  }

  _handlePing() {
    this._sendMessage({ type: MessageTypes.Ping });
  }

  _sendCompletion(invocationId, error, result) {
    this._sendMessage({
      type: MessageTypes.Completion,
      invocationId,
      error,
      result
    });
  }

  _sendMessage(message) {
    const msg = JSON.stringify(message) + '\u001e';
    this._sendRaw(msg);
  }

  _sendRaw(data) {
    if (this.socket && this.socket.readyState === 1) {
      this.socket.send({ data });
    }
  }

  _startKeepAlive() {
    this.keepAliveTimer = setInterval(() => {
      this._sendMessage({ type: MessageTypes.Ping });
    }, 15000);
  }

  _stopKeepAlive() {
    clearInterval(this.keepAliveTimer);
  }
}

export default SignalRClient;